// GLObject3D.cpp

# include "GLObject3D.h"

namespace Voltron
{
	
	GLObject3D::GLObject3D()
	{
		
	}
	
	GLObject3D::GLObject3D(int quantityVerts)
	{
		this->_positionVerts= new vec3[quantityVerts];
		this->_colorVerts= new vec3[quantityVerts];
		this->_quantityVerts = quantityVerts;
	}

	GLObject3D::GLObject3D(int quantityVerts,vec3* positionVerts, vec3* colorVerts, GLuint shaderprogram)
	{
		this->_positionVerts = positionVerts;
		this->_colorVerts = colorVerts;
		this->_quantityVerts = quantityVerts;
		
		initBuffers(shaderprogram);
	}
	
	GLObject3D::~GLObject3D();

	// Public members
	void GLObject3D::attachVertexPositionShader(GLuint shaderprogram)
	{
		makeActiveObject();

		glBindBuffer(GL_ARRAY_BUFFER, _vbo[0]);

		glUseProgram(shaderprogram);
		
	    // Initialize the vertex position attribute from the vertex shader.  When
	    // the shader and the program are linked, a table is created for the shader
	    // variables.  Here, we get the index of the vPosition variable.
	    GLuint vPositionloc = glGetAttribLocation(program, "vPosition");
	
	    // We want to set this with an array!
	    glEnableVertexAttribArray(vPositionloc);
	
	    // We map it to this offset in our current buffer (VBO) So, our position
	    // data is going into loc and contains 2 floats.  The parameters to this
	    // function are the index for the shader variable, the number of components,
	    // the type of the data, a boolean for whether or not this data is
	    // normalized (0--1), stride (or byte offset between consective attributes),
	    // and a pointer to the first component.  Note that BUFFER_OFFSET is a macro
	    // defined in the Angel.h file.
	    glVertexAttribPointer(vPositionloc, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
	}

	void GLObject3D::attachVertexColorShader(GLuint shaderprogram)
	{
		makeActiveObject();

		glBindBuffer(GL_ARRAY_BUFFER, _vbo[1]);

		glUseProgram(shaderprogram);

	    GLuint vColor = glGetAttribLocation(shaderprogram, "vColor");
	    glEnableVertexAttribArray(vColor);
	    glVertexAttribPointer(vColor, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
		
	}
	
	void GLObject3D::initBuffers()
	{
		if (_vao[0] != -1)
			glGenVertexArrays(1, _vao);
		
		glBindVertexArray(vao[0]);
		
		glGenBuffers(2, _vbo);

		glBindBuffer(GL_ARRAY_BUFFER, buffer[0]);

		// Here we copy the vertex data into our buffer on the card.  The parameters
	    // tell it the type of buffer object, the size of the data in bytes, the
	    // pointer for the data itself, and a hint for how we intend to use it.
	
	    //cout << sizeof(vertices)/sizeof(vertices[0]) << " " << sizeof(colors)/sizeof(colors[0]) << "\n";
	    glBufferData(GL_ARRAY_BUFFER, getbyteBufferSize(), _positionVerts, GL_STATIC_DRAW);

	   // Now repeat lots of that stuff for the colors
		glBindBuffer(GL_ARRAY_BUFFER, buffer[1]);
		glBufferData(GL_ARRAY_BUFFER, getbyteBufferSize(), _colorVerts, GL_STATIC_DRAW);
	
	}

	void GLObject3D::initBuffers(GLuint shaderprogram)
	{
		initBuffers();
		attachVertexPositionShader(shaderprogram);
		attachVertexColorShader(shaderprogram);
		
	}

	void GLObject3D::makeActiveObject()
	{
		glBindVertexArray(_vao[0]);
	}
	
	uint GLObject3D::getbyteBufferSize()
	{
		return sizeof(vec3) * _quantityVerts;
	}

	void GLObject3D::render()
	{
		// do nothing here. Virtual functions must be implemented
	}

	

}

#endif
